package com.ubtechinc.cruzr.libai.honglauncher.http;

import android.util.Log;
import android.util.Pair;


import com.blankj.utilcode.util.DeviceUtils;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.TimeUnit;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

public class HttpSignInterceptor implements Interceptor {
    private static final String TAG = "HttpSignInterceptor";
    private static final String HEADER_APP_ID = "X-UBT-AppId";
    private static final String HEADER_SIGN = "X-UBT-Sign";
    private static final String URL_SYNC_TIME = "https://apis.ubtrobot.com/v1/client-auth-service/api/timestamp";
    private final String mAppId;
    private final String mAppKey;
    private volatile boolean mTimeSynced;
    private volatile Pair<Long, Long> mTimePair;
    private OkHttpClient mHttpClient;
    private final String ANDROID_DEVICE_ID;

    public HttpSignInterceptor(String appId, String appKey) {
        if (appId != null && appId.length() > 0 && appKey != null && appKey.length() > 0) {
            this.mAppId = appId;
            this.mAppKey = appKey;
            ANDROID_DEVICE_ID = DeviceUtils.getAndroidID();
        } else {
            throw new IllegalArgumentException("appId or appKey arguments is empty.");
        }
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
//        this.trySyncTimeIfNecessary();
        Request originalRequest = chain.request();
        String appIdInRequest = originalRequest.header("X-UBT-AppId");
        if (appIdInRequest != null && !this.mAppId.equals(appIdInRequest)) {
            throw new IllegalStateException("X-UBT-AppId header value is different from " + this.mAppId);
        } else {
            return chain.proceed(originalRequest.newBuilder()
                    .header("X-UBT-AppId", this.mAppId)
                    .header("X-UBT-Sign", sign())
                    .header("X-UBT-DeviceId", ANDROID_DEVICE_ID)
                    .build());
        }
    }

    private void trySyncTimeIfNecessary() {
        if (!this.mTimeSynced) {
            synchronized (this) {
                if (!this.mTimeSynced) {
                    try {
                        long syncStart = System.nanoTime();
                        long returnRemoteTimestamp = this.getRemoteTimestampLocked();
                        long currentRemoteTimestamp = returnRemoteTimestamp + TimeUnit.NANOSECONDS.toSeconds((System.nanoTime() - syncStart) / 2L);
                        this.mTimePair = new Pair(System.nanoTime(), currentRemoteTimestamp);
                        this.mTimeSynced = true;
                    } catch (IOException var9) {
                        Log.e("HttpSignInterceptor", "Sync time failed before request which need sign.", var9);
                    }

                }
            }
        }
    }

    private long getRemoteTimestampLocked() throws IOException {
        if (this.mHttpClient == null) {
            this.mHttpClient = new OkHttpClient();
        }

        ResponseBody responseBody = this.mHttpClient.newCall((new Request.Builder()).url("https://apis.ubtrobot.com/v1/client-auth-service/api/timestamp").get().build()).execute().body();
        if (responseBody == null) {
            throw new IOException("Service response empty body.");
        } else {
            try {
                JSONObject resObj = new JSONObject(new String(responseBody.bytes()));
                return resObj.getLong("timestamp");
            } catch (JSONException var3) {
                throw new IOException("Service response unexpected json object.", var3);
            }
        }
    }

    private long nowSecondsForSign() {
        return this.mTimeSynced ? (Long) this.mTimePair.second + TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - (Long) this.mTimePair.first) : System.currentTimeMillis() / 1000L;
    }

    private static final String SIGN_PART_SEPARATOR = " ";

    public String sign(long timestamp) {
        return this.md5(timestamp + this.mAppKey) + " " + timestamp;
    }

    public String sign() {
        long now = System.currentTimeMillis() / 1000;
        String randStr = RandomUtils.getRandomNumbersAndLetters(10);
        String versionNum = "v2";
        StringBuilder md5Sb = new StringBuilder();
        md5Sb.append(now)
                .append(mAppKey)
                .append(randStr)
                .append(ANDROID_DEVICE_ID);
        // 规则：
        // 1. 计算当前时间戳（单位：秒）拼接 AppKey 和 1-10 位大小写字母和数字随机字符生成字符串的 MD5 值，得到签名段.
        // 2. 将签名段与先前的时间戳使用空格连接，同时使用空格连接 randStr 字符串，得到最终 X-UBT-Sign 内容.
        return md5(md5Sb.toString())
                + SIGN_PART_SEPARATOR + now
                + SIGN_PART_SEPARATOR + randStr
                + SIGN_PART_SEPARATOR + versionNum;
    }

    private String md5(String srcStr) {
        try {
            String result;
            for (result = (new BigInteger(1, MessageDigest.getInstance("MD5").digest(srcStr.getBytes()))).toString(16); result.length() < 32; result = "0" + result) {
                ;
            }

            return result;
        } catch (NoSuchAlgorithmException var3) {
            throw new IllegalStateException(var3);
        }
    }
}
